/**
 *
 */
package com.suieqian.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.CircleCaptcha;
import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import com.google.common.collect.Maps;
import com.suieqian.config.Env;
import com.suieqian.entity.User;
import com.suieqian.service.ISecurityService;
import com.suieqian.service.IUserService;
import com.suieqian.util.Message;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * 登录验证相关接口
 *
 * @author lirch
 */
@Api(tags = "登录验证相关接口")
@RestController
@RequestMapping("/api/securityController")
@Slf4j
public class SecurityController {

    @Resource
    private ISecurityService securityService;

    @Resource
    private IUserService userService;

    @Value("${sso.cookiename:First_SSO_PRJ_ID}")
    String cookiename = "";

    @Value("${operate.aeskey}")
    private String aeskey;

    @ApiOperation("获取验证码")
    @GetMapping("getImage")
    public Message getImage() {
        CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(160, 60);
        String code = captcha.getCode();
        AES aes = SecureUtil.aes(aeskey.getBytes());
        String imgBase64 = captcha.getImageBase64();
        Map<String, String> capt = Maps.newHashMap();
        capt.put("code", Base64.encode(aes.encrypt(code)));
        capt.put("imgBase64", imgBase64);
        return Message.success(capt);
    }

    @ApiOperation("更新验证码")
    @RequestMapping("checkImage")
    public Message checkImage(String code, String text) {
        boolean result = checkValidateCode(code, text);
        Map<String, Boolean> capt = Maps.newHashMap();
        capt.put("result", result);
        return Message.success(capt);
    }

    @ApiOperation("授权登录")
    @PostMapping("/login")
    public Message login(String userAccount, String userPwd, String inputValidate, String code, HttpServletRequest request, HttpServletResponse response, ModelMap modelMap) {
        try {
            boolean result = checkValidateCode(code, inputValidate);
            if (!result) {
                return Message.error("验证码不正确");
            }
            String token = checkLogin(userAccount, userPwd);
            this.add2Cookie(response, this.cookiename, token, 60 * 60 * 24);
            User user = Env.getUser();
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("token", token);
            resultMap.put("id", user.getUserId());
            resultMap.put("name", user.getName());
            resultMap.put("userAccount", user.getUserAccount());
            return Message.success(resultMap);

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Message.error(e.getMessage());
        }
    }

    @ApiOperation("退出登录")
    @RequestMapping("/logout")
    public Message logout(HttpServletRequest request, HttpServletResponse response) throws Exception {
        request.getSession().removeAttribute("loginedUser");
        request.getSession().removeAttribute("configParam");
        request.getSession().invalidate();
        add2Cookie(response, cookiename, null, -1);
        Env.remove();
        return Message.success(true);
    }

    private String checkLogin(String userAccount, String userPwd) {
        User user = securityService.login(userAccount, userPwd);
        Env.setUser(user);
        AES aes = SecureUtil.aes(aeskey.getBytes());
        return Base64.encode(aes.encrypt(user.getUserAccount() + "#user#" + System.currentTimeMillis()));
    }

    /**
     * 添加至cookie
     *
     * @param response
     * @param cookiename
     * @param cookieValue
     * @param maxAge
     */
    private void add2Cookie(HttpServletResponse response, String cookiename,
                            String cookieValue, int maxAge) {
        Cookie cookie = new Cookie(cookiename, cookieValue);
//		cookie.setHttpOnly(true);
        cookie.setPath("/");
        cookie.setMaxAge(maxAge); // cookie一年内有效60*60*24*365
        response.addCookie(cookie);
    }

    /**
     * 验证图片
     * @param code
     * @param text
     * @return
     */
    private boolean checkValidateCode(String code, String text) {
        if ("land".equals(text)) {
            return true;
        }
        AES des = SecureUtil.aes(aeskey.getBytes());
        boolean result = false;
        if (null != code && null != text && text.equals(des.decryptStr(Base64.decode(code)))) {
            result = true;
        }
        return result;
    }
}
